這幾天的文章會是一系列的,會需要一起看才比較能看懂整個ML模型的輪廓,
然而因為一天能寫的內容量有限,所以我會在前言部分稍微說明我寫到哪。
因為ML模型的訓練階段章節內容會分很多部分,我們要先確認好自己在哪個階段,
以免吸收新內容卻不知道用在內容的什麼地方。
★ML的整個「訓練過程」:這裡以監督式學習(Supervised Learning)為例
| 階段 | 要做的事情 | 簡介 | 
|---|---|---|
| ( 訓練前) | 決定資料集與分析資料 | 你想要預測的是什麼資料? 這邊需要先知道 example、label、features的概念。介紹可參考:【Day 15】,而我們這次作為範例的訓練資料集介紹在【Day 19】。 | 
| ( 訓練前) | 決定問題種類 | 依據資料,會知道是什麼類型的問題。 regression problem(回歸問題)?classification problem(分類問題)? 此處可參考:【Day 16】、與進階內容:【Day 17】 | 
| ( 訓練前) | 決定ML模型(ML models) | 依據問題的種類,會知道需要使用什麼對應的ML模型。 回歸模型(Regression model)?分類模型(Classification model)? 此處可參考:【Day 18】,神經網路(neural network)? 簡介於:【Day 25】 | 
| (模型裡面的參數) | ML模型裡面的 參數(parameters)與超參數(hyper-parameters)此處可參考:【Day 18】 | |
| ( 訓練中) 調整模型 | 評估當前模型好壞 | 損失函數(Loss Functions):使用損失函數評估目前模型的好與壞。以MSE(Mean Squared Error),RMSE(Root Mean Squared Error),交叉熵(Cross Entropy)為例。此處可參考:【Day 20】 | 
| ( 訓練中) 調整模型 | 修正模型參數 | 以 梯度下降法 (Gradient Descent)為例:決定模型中參數的修正「方向」與「步長(step size)」此處可參考:【Day 21】 | 
| ( 訓練中) 調整腳步 | 調整學習腳步 | 透過 學習速率(learning rate)來調整ML模型訓練的步長(step size),調整學習腳步。(此參數在訓練前設定,為hyper-parameter)。此處可參考:【Day 22】 | 
| ( 訓練中) 加快訓練 | 取樣與分堆 | 設定 batch size,透過batch從訓練目標中取樣,來加快ML模型訓練的速度。(此參數在訓練前設定,為hyper-parameter)。與迭代(iteration),epoch介紹。此處可參考:【Day 23】 | 
| ( 訓練中) 加快訓練 | 檢查loss的頻率 | 調整「檢查loss的頻率」,依據 時間(Time-based)與步驟(Step-based)。此處可參考:【Day 23】 | 
| ( 訓練中) 完成訓練 | (loop) -> 完成 | 重覆過程(評估當前模型好壞 -> 修正模型參數),直到能 通過「驗證資料集(Validation)」的驗證即可結束訓練。此處可參考:【Day 27】 | 
| ( 訓練後) | 訓練結果可能問題 | 「不適當的最小loss?」此處可參考:【Day 28】 | 
| ( 訓練後) | 訓練結果可能問題 | 欠擬合(underfitting)?過度擬合(overfitting)? 此處可參考:【Day 26】 | 
| ( 訓練後) | 評估 - 性能指標 | 性能指標(performance metrics):以混淆矩陣(confusion matrix)分析,包含「Accuracy」、「Precision」、「Recall」三種評估指標。簡介於:【Day 28】、詳細介紹於:【Day 29】 | 
| ( 訓練後) | 評估 - 新資料適用性 | 泛化(Generalization):對於新資料、沒看過的資料的模型適用性。此處可參考:【Day 26】 | 
| ( 訓練後) | 評估 - 模型測試 | 使用「 獨立測試資料集(Test)」測試? 使用交叉驗證(cross-validation)(又稱bootstrapping)測試? 此處可參考:【Day 27】 | 
| (資料分堆的方式) | ( 訓練前) 依據上方「模型測試」的方法,決定資料分堆的方式:訓練用(Training)、驗證用(Validation)、測試用(Test)。此處可參考:【Day 27】 | 
而今天的文章我們就要來介紹所謂的梯度下降法 (Gradient Descent)
與ML模型中參數的修正「方向」與「步長(step size)」概念。
第三章節的課程地圖:(紅字標記為本篇文章中會介紹到的章節)
Optimization
Gradient Descent
Gradient Descent
課程地圖
在昨天的章節中,我們介紹了損失函數(loss function)的計算方式,
然而損失函數loss function只能「告訴我們參數的好壞」,
我們仍需要一個「修改參數的方法」,
今天我們要介紹的梯度下降法 (Gradient Descent),就是一種「修改參數的方法」。
自己的註1:
損失函數(loss function)是判斷誤差大小的計算方法,然而還需要一個「修改參數的方法」。像這邊介紹的梯度下降法 (Gradient Descent)就是一個基於損失函數(loss function)的值去「修改參數的方法」。
自己的註2:
現在機器學習可使用於「修改參數的方法」有非常多種,然而這邊只介紹最經典的
梯度下降法 (Gradient Descent),仍有其他好的「修改參數的方法」可以使用。

梯度下降法 (Gradient Descent),是一種「搜尋參數的策略」,
他是在一個參數空間中的每個點所代表的loss上,沿著表面往下走的過程,如上圖。
自己的註:
我們從上一節可以知道一個點表示一組參數,而一組參數能算出一個loss值(代表誤差多少),
我們可以將這個「loss值的計算結果」想像成「山的高度」,而對應位置就是參數的點,
就能夠畫出像上圖的等高線圖。

然而我們通常不可能把所有的loss都計算出來,我們頂多知道要評估哪個點時,
才會去計算那一個點的loss,例如說我們可能只知道像上圖的兩個點。
但即使如此,我們仍然要知道接下來我們要往哪裡移動,才能找到最小值。
自己的註:
還記得「最小化loss」是我們的訓練目標嗎?
另外我們所謂的「修正模型參數」,也就等同於「修正點的位置」,
那「最小的loss」會在這個像山的圖的哪邊呢?
當然是山谷的地方,所以上面才說「梯度下降法」像是「沿著表面往下走的過程」。

我們把這個問題稍微拆解成兩個不同卻同樣重要的問題。
現在我們先做個簡單的假設,我們先「固定我們走一步的移動距離」,
「走一步的移動距離」又稱為,我們只討論我們「該往哪個方向移動」。

而這使得我們能得到上述的簡單演算法。
當 loss > 某一個很小的常數(epsilon)時,我們先計算方向,
然後對於模型中的參數(parameter),
設定新的值為我們現在的點加上【往我們要的方向「走幾步」乘上「步長(step size)」】,
然後針對新的點計算新的loss。

我們可以用地形圖或等高線圖的概念去想,
等高線上的每一條線代表一定的深度。
線與線的距離越近,表示那段越陡峭。
就像上面這張圖的每一個點,我們可以從點與點之間看出點移動的方式。
這就是一個從頂部邊緣開始漸漸往下走,直到走到最終的最小值。
另外一個可以注意的點是:因為我們現在固定步長(step size),所以每個點之間的距離是一樣的。
我們再來試著想一個問題,如果步長(step size)太小,我們的訓練會花很多時間。
但我們還是能夠保證能找到「可能的最小值」,
這裡會說是「可能的最小值」是因為「最小值可能不只一個」,後面我們會再討論。
自己的註1:
如果步長(
step size)太小,我們的訓練會花很多時間。
這句話也可以想像為走一步的距離小,走道目標的時間就會長。
自己的註2:
另外「最小值可能不只一個」,是因為這張圖只有一個山谷。
但想想現實生活中的山谷也應該不是只有一個吧? 這裡也是一樣的。

(如上面這張圖,從開始點到走到山谷,步長(step size)越小,到山谷花的時間自然就要越長)

既然我們說步長(step size)越小,花的時間越長,
那我們走大步一點總會比較快了吧? 然而事情也沒有這麼順利。
如果步長(step size)太大,你有可能從loss表面的其中一面甚至直接跳到另外一面,
甚至有可能整個直接跳出這個山谷中,然後到了全新未知的地方,如上圖。
因為這個原因,步長(step size)太大,很有可能導致ML模型模辦法收斂。
自己的註1:
可以想像成,人走一個超級大步,連山谷都跨出去都有可能的那麼大步。(現實中可能有點扯啦XD)
可以想像成巨人之類的XDDD,總之太大步也不行,
有可能直接跨出山谷,或跨到山谷的另外一面。
自己的註2:
這裡突然提到「收斂」一詞,其實我們確實在找谷底的過程就是在做「收斂」的動作,
「當抵達谷底時」=「收斂完成」=「找到最小的loss」=「完成學習目標」
不能收斂的原因就是跟上面所說一樣,走太大步了! 谷底都被跨過了! 找不到谷底了!

從上面的例子我們就可以知道,我們應該要指定一個剛剛好的步長(step size),
不可以太大、也不可以太小。
但想要找到這個剛剛好的值,似乎是沒那麼容易?

我們觀察左邊的圖與右邊的圖,
我們都給這兩張圖設定一樣的步長(step size),
所以從上面例子我們知道一個固定的步長(step size),
似乎沒辦法適用於所有的ML模型,那我們該怎麼改變步長(step size)呢?

我們這裡用一些斜率與曲線變化的速率,
使我們對步長(step size)與方向(direction)更有概念。
我們看上圖,圖下方表示圖上方圖曲線(此曲線就是loss的變化曲線)的各點斜率值,
我們發現值較大的地方通常比值較小的地方離底部更遠。
自己的註:
(這裡的值指的是絕對值之後的值,也就是說下圖負越多或正越多離底部越遠。)
- 如果
斜率值越小,表示我們「快要到底部了」(要走一小步)- 如果
斜率值越大,表示我們「離底部還很遠」(要走一大步)
另外再注意:
斜率是負,表示我們的「「谷底在右手邊」(向右找最小值)斜率是正,表示我們的「谷底在左手邊」(向左找最小值)
我們換一個點看,例如點B,
他有「正的斜率」,告訴我們要「向左找最小值」,
另外他的「斜率值很大」,告訴我們「要走一大步」。

我們再換另一個點看,例如點C,
他有「正的斜率」,告訴我們要「向左找最小值」,
另外他的「斜率值很小」,告訴我們「要走一小步」,以避免走過頭。

我們現在就將我們的一開始所說的「固定的步長(step size)」,
用一個新函數「computeDerivative」來取代掉,
同時這個函數也能夠同時替我們決定「要前進的方向(derivative)」
我們將原本的點減掉「loss值的偏微分」,以獲得新的點。
自己的註:
也就是說,我們對loss值偏微分,依照剛剛上面的概念,
我們能同時獲得「應該前進的方向」與「要走多遠」。
啊對了,這方法就叫做梯度下降法 (Gradient Descent),
這邊就已經介紹完了XDD,梯度就是指「loss的偏微分」,下降就是「找谷底」。
「loss的偏微分」:y是loss值,偏微的對象x是所有模型內的參數(parameter),
可以參考更上方的二維圖:「y反應loss值的大小,而x反應的是參數所在位置。」
而上圖中的點也可以注意他的變化:「該走快時走很快,該走慢時走很慢,且走的方向很正確。」
我們似乎找到了一個非常好的方法,
他能幫我們找到合適的步長(step size)與要前進的方向(direction),
但這樣就沒有問題了嗎?
以經驗來說,ML的種種問題集之中,我們所能建的loss表面,
這個算法通常會花費較多的時間,可能會找到次小值而非最小值,甚至是沒有完成。
自己的註:
- 「
花費較多的時間」:梯度下降法 (Gradient Descent)相對比較新的算法來說,確實較慢,但並非不能用(下面也有提到XD)- 「
找到次小值而非最小值」:這確實是常見問題,我們可以想像等高線上有很多山谷,我們從找到第一個點時,就會開始往一個山谷的谷底直直前進。然而,如果這個山谷不是全部山谷最深的,那我們就找不到最深的山谷。不過目前也已經有新方法能解決這個搜索的問題。- 「
沒有完成」:有時候花費時間太長,而且特別是在接近底部的時候,可以想像一個問題,我們在做「y = 1/x」的畫圖時,那種趨近x軸卻永遠碰不到x軸的感覺(y無限接近0, x無限增加),收斂的感覺也很像這樣,一直無限接近,但遲遲沒有到。
但梯度下降法 (Gradient Descent)仍然是一個常被使用的方法,
這也表示像上述可能會出現問題的資料集,我們往往很少會碰到。
coursera - Launching into Machine Learning 課程
若圖片有版權問題請告知我,我會將圖撤掉